package com.cloud.common.ratelimit.aspect;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.RateLimiter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 操作日志使用spring event异步入库
 *
 * @author xn
 */
@Aspect
@Slf4j
public class RateLimitAspect {

    /**
     * 不同的接口，不同的流量控制
     */
    private final Map<String, RateLimiter> limitMap = Maps.newConcurrentMap();

    @SneakyThrows
    @Before("@annotation(ratelimit)")
    public void before(JoinPoint point, com.cloud.common.ratelimit.annotation.RateLimit ratelimit) {
        Signature signature=point.getSignature();
        String key=signature.getDeclaringTypeName()+"."+signature.getName();
        double limit=ratelimit.limit();
        int timeOut=ratelimit.timeOut();
        RateLimiter rateLimiter=limitMap.computeIfAbsent(key,v->RateLimiter.create(limit));

        boolean acquire=rateLimiter.tryAcquire(timeOut,TimeUnit.SECONDS);
        if(!acquire){
            log.info("接口[{}]已被限流",key);
            throw new RuntimeException("系统繁忙，请稍后再试");
        }

    }
}
